#include "opencv2/highgui.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/videoio.hpp"
#include "src/TGPolygon.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;

RNG rng(0);
Mat backGround;
TGPolygon polygon1, polygon2, polygon3;
Scalar c1(255, 0, 0), c2(0, 255, 0);

void generateRandomPolygon(int n, TGPolygon& polygon) {
    polygon.init();
    polygon3.data.reserve(n);
    for(int i = 0; i < n; i ++) {
        polygon.data.emplace_back(rng.uniform(0, 11)*100, rng.uniform(0, 11)*100);
    }
    antiClockwiseAndRemoveDuplicate(polygon);
}

void drawPolygon(Mat& img, TGPolygon& polygon, const Scalar& color, bool fill) {
    vector<Point>pts;
    pts.reserve(polygon.data.size());
    for(const auto& p : polygon.data) {
        pts.emplace_back(int(p.x), int(p.y));
    }
    if(!fill)
        polylines(img, pts, true, color, 2);
    else{
        fillPoly(img, pts, color);
    }
    imshow("Main", img);
}

void onMouse(int event, int x, int y, int flags, void* param) {
    if(event == EVENT_LBUTTONDOWN) {
        bool flag = polygon1.isContainPoint({1.0*x, 1.0*y});
        //cout << x << " " << y << " " << flag << endl;
    }
}

int main() {

    // generateRandomPolygon(4, polygon1);
    // generateRandomPolygon(4, polygon2);

    polygon1.data = {{100, 150}, {200,250},{300,200}};
    polygon2.data = {{150,150}, {150,200},{200,200}, {200,150} };
    // polygon2.data = {{100, 300}, {300, 300}, {200, 100}};
    
    antiClockwiseAndRemoveDuplicate(polygon1);
    antiClockwiseAndRemoveDuplicate(polygon2);
    //getAllIntersectionPoints(polygon1, polygon2, polygon3);

    SHClip(polygon1, polygon2, polygon3);

    // for(auto& p : polygon3.data) {
    //     printf("%.2f, %.2f\n", p.x, p.y);
    // }

    backGround = Mat(1000, 1000, CV_8UC3, Scalar(255, 255, 255));
    drawPolygon(backGround, polygon1, c1, false);
    drawPolygon(backGround, polygon2, c1, false);
    drawPolygon(backGround, polygon3, c2, true);
    setMouseCallback("Main", onMouse);
    waitKey(0);
    destroyAllWindows();
    
    // for(auto& p : polygon1.data) {
    //     printf("(%.2f, %.2f)\n", p.x, p.y);
    // }

    // cout << polygon1.isContainPoint({5, 5}) << endl;

    return 0;
}